export function parse(source: string): Promise<{ [key: string]: string }> {
  const lines = source.split(LINE_BOUNDARY)
  return parseLines(lines)
}

const SECTION = new RegExp(/\s*\[([^\]]+)]/)

const KEY = new RegExp(/\s*(.*?)\s*[=:]\s*(.*)/)

const COMMENT = new RegExp(/^\s*[#]/)

const LINE_BOUNDARY = new RegExp(/\r\n|[\n\r\u0085\u2028\u2029]/g)

function parseLines(lines: string[]): Promise<{ [key: string]: string }> {
  return new Promise((resolve, reject) => {
    let sections = {}
    let curSec = null

    for (let i = 0; i < lines.length; i++) {
      let line = lines[i]
      let lineNumber = i + 1

      if (!line || line.match(COMMENT)) continue
      let res = SECTION.exec(line)
      if (res) {
        const header = res[1]
        curSec = {}
        sections[header] = curSec
      } else if (!curSec) {
        if (line.startsWith('root')) {
          res = KEY.exec(line)
          if (res && res[1] === 'root') {
            sections['root'] = res[2]
          } else {
            reject(`parse error:${lineNumber}:\n${line}`)
            break
          }
        } else {
          reject(`missing section header in line:${lineNumber}:\n${line}`)
          break
        }
      } else {
        res = KEY.exec(line)
        if (res) {
          const key = res[1]
          curSec[key] = res[2]
        } else {
          reject(`parse error:${lineNumber}:\n${line}`)
          break
        }
      }
    }

    resolve(sections)
  })
}